package com.demo.schedule.his;

import com.alibaba.fastjson.JSON;
import com.demo.datasource.SpringUtils;
import com.demo.entity.Patient;
import com.demo.entity.PatientTransition;
import com.demo.entity.his.HisPatient;
import com.demo.enums.PatientStatusEnum;
import com.demo.mapper.DepartmentMapper;
import com.demo.mapper.HisMapper;
import com.demo.mapper.PatientMapper;
import com.demo.service.IPatientService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
public class SyncHisDataThread extends Thread {

    private HisMapper hisMapper;
    private IPatientService patientService;
    private PatientMapper patientMapper;
    private DepartmentMapper departmentMapper;

    public SyncHisDataThread() {
        hisMapper = SpringUtils.getBean(HisMapper.class);
        patientService = SpringUtils.getBean(IPatientService.class);
        patientMapper = SpringUtils.getBean(PatientMapper.class);
        departmentMapper = SpringUtils.getBean(DepartmentMapper.class);
    }

    @SneakyThrows
    @Override
    public void run() {

        // 前置检测 his 数据库是否通畅，如果不通则不继续往下执行
        try {
            hisMapper.queryPatientList(0);
        } catch (Exception ex) {
            log.error("his 数据库不通，不在往下执行数据采集任务", ex);
            return;
        }


        // 查询所有部门
        List<Integer> allDeptNo = departmentMapper.getAllDeptSn();
        // 全院病人列表
        List<HisPatient> hisPatients = new ArrayList<>();
        List<HisPatient> hisDeptPatients = new ArrayList<>();
        for (Integer deptSn : allDeptNo) {
            hisDeptPatients.clear();
            hisDeptPatients = hisMapper.queryPatientList(deptSn);
            hisDeptPatients = hisDeptPatients.stream().map(item -> {
                item.setDeptSn(deptSn);
                return item;
            }).collect(Collectors.toList());
            hisPatients.addAll(hisDeptPatients);
        }

        // vte 存量患者信息[不包括已出院患者]
        List<Patient> vtePatients = patientMapper.selectInHospitalPatients();
        List<Integer> vtePatientIds = vtePatients.stream().map(Patient::getHisPatientId).collect(Collectors.toList());

        // 患者数据分类
        List<HisPatient> xinRuList = new ArrayList<>();
        List<HisPatient> zhuanKeList = new ArrayList<>();
        List<Patient> chuYuanList = new ArrayList<>();

        for (HisPatient hisPatient : hisPatients) {
            if (StringUtils.isBlank(hisPatient.getSerialId())) {
                continue;
            }
            Integer admissionId = Integer.parseInt(hisPatient.getAdmissionId().trim());

            if (!vtePatientIds.contains(admissionId)) {
                // 新入
                xinRuList.add(hisPatient);
            } else if (vtePatientIds.contains(admissionId)) {
                boolean present = vtePatients.stream()
                        .filter(item -> Objects.equals(item.getHisPatientId(), admissionId)
                                && StringUtils.isNotBlank(hisPatient.getWardId())
                                && item.getWardId() != Integer.parseInt(hisPatient.getWardId().trim()))
                        .findFirst().isPresent();
                if (present) {
                    // 转科
                    zhuanKeList.add(hisPatient);
                }
            }
        }
        List<String> hisAdmissionIds = hisPatients.stream().map(HisPatient::getAdmissionId).collect(Collectors.toList());
        for (Patient vtePatient : vtePatients) {
            if (!hisAdmissionIds.contains(String.valueOf(vtePatient.getHisPatientId()))) {
                // 出院
                chuYuanList.add(vtePatient);
            }
        }

        // 针对分类数据进行对应的操作
        addPatient(xinRuList);
        zhuanKePatient(zhuanKeList);
        chuYuanPatient(chuYuanList);
    }

    public void addPatient(List<HisPatient> hisPatients) {
        for (HisPatient hisPatient : hisPatients) {
            Patient patient = new Patient();
            try {
                patient.toPatient(hisPatient);
                patientService.addPatient(patient);
            } catch (Exception e) {
                log.error("添加新入 HisPatient 异常   hisPatient={}", JSON.toJSONString(hisPatient));
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        System.out.println(Integer.parseInt(String.valueOf(1707323)));
    }

    public void zhuanKePatient(List<HisPatient> zhuanKePatients) {
        for (HisPatient zhuanKePatient : zhuanKePatients) {
            try {
                Patient patient = patientMapper.queryByHisPatientId(Integer.parseInt(zhuanKePatient.getSerialId()));
                if (patient == null) {
                    continue;
                }
                PatientTransition patientTransition = new PatientTransition();
                patientTransition.setAdmissionId(zhuanKePatient.getAdmissionId());
                patientTransition.setBedId(zhuanKePatient.getSerialId());
                patientTransition.setDeptSn(zhuanKePatient.getDeptSn());
                if (StringUtils.isNotBlank(zhuanKePatient.getWardId())) {
                    patientTransition.setWardId(Integer.parseInt(zhuanKePatient.getWardId().trim()));
                }
                patientService.changPatientStatus(patient.getHisPatientId(), PatientStatusEnum.CHU_YUAN.getValue(), 1, patientTransition);
            } catch (Exception e) {
                log.error("转科异常，转科病人 zhuanKePatient={}", JSON.toJSONString(zhuanKePatient));
                e.printStackTrace();
            }
        }
    }

    public void chuYuanPatient(List<Patient> chuYuanPatient) {
        PatientTransition patientTransition = new PatientTransition();
        for (Patient patient : chuYuanPatient) {
            try {
                patientService.changPatientStatus(patient.getHisPatientId(), PatientStatusEnum.CHU_YUAN.getValue(), 0, patientTransition);
            } catch (Exception e) {
                log.error("出院异常，出院病人 patient={}", JSON.toJSONString(patient));
                e.printStackTrace();
            }
        }
    }

}
